package hongcaosp.app.android.video.player;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.content.Context;
import android.graphics.Rect;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.tencent.liteav.demo.play.SuperPlayerModel;

import java.util.Random;
import java.util.concurrent.TimeUnit;

import hongcaosp.app.android.R;
import hongcaosp.app.android.common.BaseHolder;
import hongcaosp.app.android.login.UserToken;
import hongcaosp.app.android.modle.bean.IUser;
import hongcaosp.app.android.modle.bean.IVideo;
import hongcaosp.app.android.video.PlayConstant;
import hongcaosp.app.android.video.VisiblePage;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import xlj.lib.android.base.utils.GlideUtils;
import xlj.lib.android.base.utils.ScreenUtils;

public class VideoHolder extends BaseHolder<IVideo> implements VideoProxy {
    public SimplePlayerView playerView;
    private ImageView playBtn,userFlagIV,likeIV;
    private TextView likeTV,commentIV,atUserTV,descripTV,shareTV;
    private IVideo videoPlayer;
    private ImageView userLogo,musicLogo,coverIV;
    private Context context;
    private VideoClickListener videoClickListener;
    private int state;
    private boolean isPrepareStart;
    private FrameLayout ratioFrameLayout;
    private FrameLayout infoFrame;
    private static PlayCountListener playCountListener;

    private TextView errorTV;

    private VisiblePage obj;

    private boolean fillScreen;
    private Random random = new Random();
    private float[] rotation = new float[]{-35f, -25f, 0f, 25f, 35f};
    private Disposable disposable;

    public static void setPlayCountListener(PlayCountListener playCountListener) {
        VideoHolder.playCountListener = playCountListener;
    }

    public void setFillScreen(boolean fillScreen) {
        this.fillScreen = fillScreen;
        FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) infoFrame.getLayoutParams();
        if (fillScreen) {
            layoutParams.bottomMargin = (int) context.getResources().getDimension(R.dimen.tab_height);
        } else {
            layoutParams.bottomMargin = 0;
        }
        infoFrame.setLayoutParams(layoutParams);
    }

    public VideoHolder(View itemView, final Context context, final VisiblePage obj) {
        super(itemView);
        userLogo = itemView.findViewById(R.id.user_logo);
        playerView = itemView.findViewById(R.id.player);
        playBtn = itemView.findViewById(R.id.btn_play);
        shareTV = itemView.findViewById(R.id.share);
        coverIV = itemView.findViewById(R.id.video_cover);
        errorTV = itemView.findViewById(R.id.error_toast);
        ratioFrameLayout = itemView.findViewById(R.id.ratio_fm);
        infoFrame = itemView.findViewById(R.id.info_frame);
        this.context = context;
        this.obj = obj;
        playerView.setIsLoop(true);
        playerView.setPlayerStateListener(new SimplePlayerView.PlayerStateListener() {
            @Override
            public void onPrepare() {
                errorTV.setVisibility(View.GONE);
                state = 2;
                Log.i("VideoHolder","onPrepare:" + getData().getVideoUrl());
            }

            @Override
            public void onStart() {
                state = 1;
                playBtn.setVisibility(View.GONE);
                Log.i("VideoHolder","onStart:" + getData().getVideoUrl());
                PlayVideoManager.getInstance().onPlay(VideoHolder.this, VideoHolder.this.obj);
            }

            @Override
            public void onPause() {
                Log.i("VideoHolder","onPause:" + getData().getVideoUrl());
                playBtn.setVisibility(View.VISIBLE);
                state = 2;
//                isPrepareStart = false;
            }

            @Override
            public void onStop() {
                playBtn.setVisibility(View.VISIBLE);
                state = 3;
//                isPrepareStart = false;
                coverIV.setVisibility(View.VISIBLE);
            }

            @Override
            public void onPlayProgress(int progress, int duration) {
//                state = 1;
            }

            @Override
            public void onFirstFrame() {
//                state = 9;
                Log.i("VideoHolder","onFirstFrame:" + getData().getVideoUrl() );
                if (!PlayConstant.isPlayOk ||  !isPrepareStart || (obj != null && !obj.isVisible())) {
                    pauseVideo();
                }
                coverIV.setVisibility(View.GONE);
            }

            @Override
            public void onLoading() {
//                state = 10;
                Log.i("VideoHolder","onLoading:" + getData().getVideoUrl() );
            }

            @Override
            public void onLoadEnd() {
                state = 11;
                Log.i("VideoHolder","onLoadEnd:" + getData().getVideoUrl() );
            }

            @Override
            public void onFailed(String message) {
                errorTV.setText(message);
                errorTV.setVisibility(View.VISIBLE);
                playBtn.setVisibility(View.GONE);
            }
        });
        playerView.setOnTouchListener(new View.OnTouchListener() {
            private int count = 0;
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    count ++;
                    if (count == 1) {
                        disposable = Observable.timer(300,TimeUnit.MILLISECONDS)
                                .subscribeOn(Schedulers.single())
                                .observeOn(AndroidSchedulers.mainThread())
                                .subscribe(new Consumer<Long>() {
                                    @Override
                                    public void accept(Long aLong) throws Exception {
                                        count = 0;
                                        //执行单击事件
                                        singleClickListener();
                                    }
                                });
                    } else if (count == 2) {
                        count = 0;
                        disposable.dispose();
                        //执行双击事件
                        doubleClickListener(event.getX(),event.getY());
                    }
                }
                return true;
            }
        });

        likeTV = itemView.findViewById(R.id.like_count);
        likeIV = itemView.findViewById(R.id.like_iv);
        commentIV = itemView.findViewById(R.id.comment_count);
        atUserTV = itemView.findViewById(R.id.at_user);
        descripTV = itemView.findViewById(R.id.descrip);

        userFlagIV = itemView.findViewById(R.id.user_flag);

        musicLogo = itemView.findViewById(R.id.music_logo);

        likeIV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (videoPlayer != null && videoClickListener != null) {
                    if (!videoPlayer.isLiked()) {
                        videoClickListener.onLike(videoPlayer, VideoHolder.this);
                    } else {
                        videoClickListener.unLike(videoPlayer, VideoHolder.this);
                    }
                }
            }
        });

        shareTV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (videoClickListener != null) {
                    videoClickListener.onShare(videoPlayer);
                }
            }
        });

        userFlagIV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (videoPlayer != null && videoPlayer.getAuthor() != null) {
                    if (videoClickListener == null) return;
                    if (!videoPlayer.getAuthor().meFollowTa()) {
                        videoClickListener.onFollow(videoPlayer,VideoHolder.this);
                    } else {
                        videoClickListener.unFollow(videoPlayer,VideoHolder.this);
                    }

                }
            }
        });

        commentIV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (videoPlayer != null && videoClickListener != null) {
                    videoClickListener.onComment(videoPlayer,VideoHolder.this);
                }
            }
        });

        userLogo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (videoPlayer != null && videoClickListener != null) {
                    videoClickListener.onUserClick(videoPlayer.getAuthor());
                }
            }
        });
    }

    private void singleClickListener() {
        if (state == 1 || state >= 9) {
            pauseVideo();
        } else if (state == 2) {
            resumeVideo();
        } else {
            playVideo();
        }
    }

    private void doubleClickListener(float x,float y) {
        if (videoClickListener != null && videoPlayer != null && !videoPlayer.isLiked()) {
            videoClickListener.onLike(videoPlayer, VideoHolder.this);
        }
        x = x - 120;
        y = y - 220;
        final ImageView view = new ImageView(context);
        view.setScaleType(ImageView.ScaleType.FIT_XY);
        FrameLayout.LayoutParams fllp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,FrameLayout.LayoutParams.WRAP_CONTENT);
        fllp.leftMargin = (int) x;
        fllp.topMargin = (int) y;
        fllp.width = 220;
        fllp.height = 220;
        view.setLayoutParams(fllp);
        view.setImageResource(R.drawable.icon_like_big_selected);

        ObjectAnimator ani1 = ObjectAnimator.ofFloat(view,"scaleX",2f, 0.9f);
        ani1.setDuration(100);
        ani1.setStartDelay(0);
        ani1.setInterpolator(new LinearInterpolator());

        ObjectAnimator ani2 = ObjectAnimator.ofFloat(view,"scaleY",2f, 0.9f);
        ani2.setDuration(100);
        ani2.setStartDelay(0);
        ani2.setInterpolator(new LinearInterpolator());

        ObjectAnimator ani3 = ObjectAnimator.ofFloat(view,"rotation",rotation[random.nextInt(4)]);
        ani3.setDuration(0);
        ani3.setStartDelay(0);
        ani3.setInterpolator(new TimeInterpolator() {
            @Override
            public float getInterpolation(float input) {
                return input;
            }
        });

        ObjectAnimator ani4 = ObjectAnimator.ofFloat(view,"alpha",0, 1f);
        ani4.setDuration(100);
        ani4.setStartDelay(0);
        ani2.setInterpolator(new LinearInterpolator());

        ObjectAnimator ani5 = ObjectAnimator.ofFloat(view,"scaleX",0.9f, 1f);
        ani5.setDuration(50);
        ani5.setStartDelay(50);
        ani5.setInterpolator(new LinearInterpolator());

        ObjectAnimator ani6 = ObjectAnimator.ofFloat(view,"scaleY",0.9f, 1f);
        ani6.setDuration(50);
        ani6.setStartDelay(50);
        ani6.setInterpolator(new LinearInterpolator());

        ObjectAnimator ani7 = ObjectAnimator.ofFloat(view,"translationY",0, -60f);
        ani7.setDuration(100);
        ani7.setStartDelay(100);
        ani7.setInterpolator(new LinearInterpolator());

        ObjectAnimator ani8 = ObjectAnimator.ofFloat(view,"alpha",1f, 0);
        ani8.setDuration(100);
        ani8.setStartDelay(0);
        ani8.setInterpolator(new LinearInterpolator());

        ObjectAnimator ani9 = ObjectAnimator.ofFloat(view,"scaleX",1f, 3f);
        ani9.setDuration(100);
        ani9.setStartDelay(100);
        ani9.setInterpolator(new LinearInterpolator());

        ObjectAnimator ani10 = ObjectAnimator.ofFloat(view,"scaleY",1f, 3f);
        ani10.setDuration(100);
        ani10.setStartDelay(200);
        ani10.setInterpolator(new LinearInterpolator());

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playSequentially(ani1,ani2,ani3,ani4,ani5,ani6,ani7,ani8,ani9,ani10);
        animatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                playerView.removeView(view);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        playerView.addView(view);
        animatorSet.start();
    }

    public void setVideoClickListener(VideoClickListener videoClickListener) {
        this.videoClickListener = videoClickListener;
    }

    @Override
    public void setData(final IVideo iVideo) {
        super.setData(iVideo);
        this.videoPlayer = iVideo;
        if (iVideo.getAuthor() != null) {
            freshUserFlag();
            atUserTV.setText("@" + iVideo.getAuthor().getUserName());
            GlideUtils.loadCircleImage(context,iVideo.getAuthor().getUserLogo(),userLogo,R.drawable.icon_head);
        } else {
            Glide.with(context).load("").placeholder(R.drawable.icon_head).into(userLogo);
        }
        coverIV.setVisibility(View.VISIBLE);


        freshForwords();

        freshComment();

        errorTV.setVisibility(View.GONE);

        descripTV.setText(iVideo.getDescrip());

        freshLike();
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) ratioFrameLayout.getLayoutParams();
        if (videoPlayer.getHeightRatio() < 1.5) {
            lp.height = (int) (ScreenUtils.getScreenWidth(context) * videoPlayer.getHeightRatio());
            coverIV.setScaleType(ImageView.ScaleType.FIT_CENTER);
        } else {
            lp.height = FrameLayout.LayoutParams.MATCH_PARENT;
            coverIV.setScaleType(ImageView.ScaleType.CENTER_CROP);
        }
        ratioFrameLayout.setLayoutParams(lp);
        playerView.post(new Runnable() {
            @Override
            public void run() {
                Glide.with(context).load(iVideo.getVideoImage()).diskCacheStrategy(DiskCacheStrategy.SOURCE)
                        .into(coverIV);
                if (obj == null || obj.isVisible()) {
                    if (!isCover()) {
                        prepare(true);
                    }
                }
            }
        });
    }

    public boolean isCover() {
        if (userLogo == null) return true;
        boolean cover = false;
        Rect rect = new Rect();
        cover = userLogo.getGlobalVisibleRect(rect);
        if (cover) {
            if (rect.width() >= userLogo.getMeasuredWidth() && rect.height() >= userLogo.getMeasuredHeight()) {
                return !cover;
            }
        }
        return true;
    }

    public void freshForwords() {
        shareTV.setText(videoPlayer.getForwardCounts() + "");
    }

    public void freshComment() {
        commentIV.setText(videoPlayer.getCommentCount() + "");
    }

    public void freshLike() {
        likeIV.setSelected(videoPlayer.isLiked());
        likeTV.setText(videoPlayer.getLikeCount() + "");
    }

    public void freshUserFlag() {
        if (videoPlayer.getAuthor() != null && !UserToken.getDefault().isCurrentUser(videoPlayer.getAuthor().getUserId())) {
            if (videoPlayer.getAuthor().meFollowTa()) {
                userFlagIV.setImageResource(R.drawable.icon_follow);
            } else {
                userFlagIV.setImageResource(R.drawable.icon_add);
            }
            userFlagIV.setVisibility(View.VISIBLE);
        } else {
            userFlagIV.setVisibility(View.GONE);
        }
    }

    private void prepare(boolean isStart) {
        Log.i("VideoHolder", "playVideo " + isStart);
        isPrepareStart = isStart;
        SuperPlayerModel superPlayerModel = new SuperPlayerModel();
        superPlayerModel.videoURL = videoPlayer.getVideoUrl();
//        if (videoPlayer.getHeightRatio() > 1.5) {
//            playerView.setFullScreen(true);
//        } else {
//            playerView.setFullScreen(false);
//        }
        playerView.prepareWithMode(superPlayerModel,true);
        if (playCountListener != null && videoPlayer != null) {
            playCountListener.onPlay(videoPlayer.getVid());
        }
    }

    @Override
    public void playVideo() {
        if (state > 2 || state == 0) {
            prepare(true);
        } else {
            if (state == 1)return;
            resumeVideo();
        }
    }
    @Override
    public void resumeVideo() {
        freshComment();
        Log.i("VideoHolder","resumeVideo");
        if (state == 2) {
            if (!isCover()) {
                playerView.onResume();
            }
        }
    }
    @Override
    public void pauseVideo() {
        isPrepareStart = false;
        Log.i("VideoHolder","pauseVideo");
        playerView.onPause();
    }
    @Override
    public void stopVideo() {
        isPrepareStart = false;
        Log.i("VideoHolder","stopVideo:" + videoPlayer.getVideoUrl());
        playerView.stopPlay();
    }
    @Override
    public void release() {
        isPrepareStart = false;
        Log.i("VideoHolder","releaseVideo");
        playerView.stopPlay();
    }

    @Override
    public void getLocalVisibleRect(Rect rect) {
        playerView.getLocalVisibleRect(rect);
    }

    @Override
    public int getHeight() {
        return playerView.getHeight();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null || !(obj instanceof VideoHolder) || this.videoPlayer == null) {
            return false;
        }
        VideoHolder that = (VideoHolder) obj;

        return this.videoPlayer.equals(that.videoPlayer);
    }

    public interface VideoClickListener {
        void onUserClick(IUser user);
        void onShare(IVideo videoPlayer);
        void onLike(IVideo videoPlayer, VideoHolder videoHolder);
        void unLike(IVideo videoPlayer, VideoHolder videoHolder);
        void onFollow(IVideo videoPlayer, VideoHolder videoHolder);
        void unFollow(IVideo videoPlayer, VideoHolder videoHolder);
        void onComment(IVideo videoPlayer, VideoHolder videoHolder);
    }

    public IVideo getVideoPlayer() {
        return videoPlayer;
    }
}
